package com.glsc.ngateway.ldap.schedule;

import com.glsc.ngateway.common.base.domain.mysql.gateway.ldap.LdapEhrComp;
import com.glsc.ngateway.common.base.domain.mysql.gateway.ldap.LdapEhrDept;
import com.glsc.ngateway.common.base.domain.mysql.gateway.ldap.LdapEhrEmp;
import com.glsc.ngateway.common.base.domain.oracle.ecology.Hrmdepartment;
import com.glsc.ngateway.common.base.domain.oracle.ecology.Hrmresource;
import com.glsc.ngateway.common.base.domain.oracle.ecology.Hrmsubcompany;
import com.glsc.ngateway.common.base.domain.sqlserver.glsec.TAmEhrDeptinfoEntity;
import com.glsc.ngateway.common.base.domain.sqlserver.glsec.TAmEhrEmpEntity;
import com.glsc.ngateway.common.base.enums.OaHrmresourceStatusEnum;
import com.glsc.ngateway.common.base.repo.mysql.gateway.ldap.LdapEhrCompRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.ldap.LdapEhrDeptRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.ldap.LdapEhrEmpRepo;
import com.glsc.ngateway.common.base.repo.oracle.ecology.HrmdepartmentRepository;
import com.glsc.ngateway.common.base.repo.oracle.ecology.HrmjobtitlesRepository;
import com.glsc.ngateway.common.base.repo.oracle.ecology.HrmresourceRepository;
import com.glsc.ngateway.common.base.repo.oracle.ecology.HrmsubcompanyRepository;
import com.glsc.ngateway.common.base.repo.sqlserver.glsec.TAmEhrDeptinfoRepo;
import com.glsc.ngateway.common.base.repo.sqlserver.glsec.TAmEhrEmpRepo;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class ScheduledJobs {

    private static final Logger logger = LoggerFactory.getLogger(ScheduledJobs.class);

    private static final String EHR_STATUS_DEPART = "1";
    @Resource
    private LdapEhrEmpRepo ldapEhrEmpRepo;
    @Resource
    private LdapEhrDeptRepo ldapEhrDeptRepo;
    @Resource
    private LdapEhrCompRepo ldapEhrCompRepo;
    @Resource
    private TAmEhrEmpRepo ehrEmpRepo;
    @Resource
    private TAmEhrDeptinfoRepo ehrDeptRepo;
    @Resource
    private HrmresourceRepository oaEhrRepo;
    @Resource
    private HrmdepartmentRepository oaDeptRepo;
    @Resource
    private HrmsubcompanyRepository oaCompRepo;
    @Resource
    private HrmjobtitlesRepository oaJobRepo;

    //    @Scheduled(cron = "0 58 1 * * ?")
    public void syncEhrDataTask() {
        logger.info("每日同步ehr员工、部门信息开始");
        int errorFlag = 0;
        try {
            syncEmp();
        } catch (Exception e) {
            errorFlag =1 ;
            String errMsg = "每日同步ehr员工信息异常，原因：" + e.getMessage();
            logger.error(errMsg, e);
        }
        //由于部门名称存在重复，需要先同步公司，用公司区分同名部门
        try {
            syncComp();
        } catch (Exception e) {
            errorFlag =1 ;
            String errMsg = "每日同步ehr公司信息异常，原因：" + e.getMessage();
            logger.error(errMsg, e);
        }
        try {
            syncDept();
        } catch (Exception e) {
            errorFlag =1 ;
            String errMsg = "每日同步ehr部门信息异常，原因：" + e.getMessage();
            logger.error(errMsg, e);
        }

        logger.info("每日同步ehr员工、部门、公司信息结束");
        if (errorFlag == 1){
            throw new RuntimeException("syncEhrDataTask");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public List<LdapEhrEmp> syncEmp() {
        //每日同步ehr员工、部门信息
        //A1.采集数据
        List<TAmEhrEmpEntity> ehrList = ehrEmpRepo.getEVMEmpInfoList();
        //A2.初步筛选。 过滤出在oa中 状态为0 1 2 3 的员工
        //Status状态字典：0：试用  1：正式  2：临时  3：试用延期  4：解聘  5：离职  6：退休  7：无效
        List<Hrmresource> oaList = oaEhrRepo.findAll();
        Map<Integer, Hrmdepartment> deptMap = oaDeptRepo.findAll().stream().collect(Collectors.toMap(Hrmdepartment::isId, o -> o));
        logger.info("员工信息采集-ehr:{}条", CollectionUtils.isEmpty(ehrList) ? 0 : ehrList.size());
        logger.info("员工信息采集-oa:{}条", CollectionUtils.isEmpty(oaList) ? 0 : oaList.size());
        Map<String, TAmEhrEmpEntity> ehrAccMap = ehrList.stream()
                .collect(Collectors.toMap(TAmEhrEmpEntity::getBadge, o -> o, (o1, o2) -> o1));
        List<LdapEhrEmp> ldapList = Collections.EMPTY_LIST;
        if (!CollectionUtils.isEmpty(oaList)) {
            ldapList = oaList.stream()
                    .filter(o -> Strings.isNotBlank(o.getLoginid()) || Strings.isNotBlank(o.getWorkcode()))
                    .map(oaEmp -> {
                        LdapEhrEmp ldap = new LdapEhrEmp();
                        String account = Strings.isNotBlank(oaEmp.getLoginid()) ? oaEmp.getLoginid() : oaEmp.getWorkcode();
                        if (ehrAccMap.containsKey(account)) {
                            TAmEhrEmpEntity ehrEmp = ehrAccMap.get(account);
                            org.springframework.beans.BeanUtils.copyProperties(ehrEmp, ldap);
                            ldap.setJobTitle(ehrEmp.getJobTitle());
                        }
                        ldap.setBadge(account);
                        Hrmdepartment hrmdepartment = deptMap.get(oaEmp.getDepartmentid());
                        ldap.setDepid(Objects.nonNull(hrmdepartment) && Strings.isNotBlank(hrmdepartment.getOutkey()) ? Integer.valueOf(hrmdepartment.getOutkey()) : null);
                        ldap.setTitle(Objects.nonNull(hrmdepartment) ? hrmdepartment.getDepartmentname() : null);
                        ldap.setEmail(oaEmp.getEmail());
                        ldap.setMobile(oaEmp.getMobile());
                        ldap.setName(oaEmp.getLastname());
                        ldap.setStatus(String.valueOf(oaEmp.getStatus()));
                        ldap.setOaUserId(oaEmp.isId());
                        ldap.setOaDeptId(oaEmp.getDepartmentid());
                        ldap.setOaCompId(oaEmp.getSubcompanyid1());
                        ldap.setMessagerUrl(oaEmp.getMessagerurl());
                        return ldap;
                    })
                    .collect(Collectors.toList());
            ldapEhrEmpRepo.saveAll(ldapList);
        }
        logger.info("syncEhrDataTask同步员工信息，新增{}条", ldapList.size());
        Set<String> ldapBadgeSet = CollectionUtils.isEmpty(ldapList) ? Collections.EMPTY_SET : ldapList.stream().map(LdapEhrEmp::getBadge).collect(Collectors.toSet());
        logger.info("采集现有员工信息" + ldapBadgeSet.size() + "条");
        List<LdapEhrEmp> ldapExistList = ldapEhrEmpRepo.findAll();
        List<LdapEhrEmp> ldapNonExistList = ldapExistList.stream()
                .filter(e -> {
                    if (!ldapBadgeSet.contains(e.getBadge()) && !OaHrmresourceStatusEnum.isAlive(e.getStatus())) {
                        logger.info("本地有且状态是0在职，ehr没有该员工，说明离职，更新状态。badge=" + e.getBadge());
                        e.setStatus(String.valueOf(OaHrmresourceStatusEnum.离职.getCode()));
                        return true;
                    }
                    return false;
                })
                .collect(Collectors.toList());
        ldapEhrEmpRepo.saveAllAndFlush(ldapNonExistList);
        //A2.删除ehremp中间表中数据
        //this.truncateEhrEmp();
        //A3.保存数据到ehremp中间表
        //this.saveAllEmp(ldapList);

        //A4.同步t_am_ehr_emp表数据到t_am_user中
        //this.syncEmpInfo();
        logger.info("syncEhrDataTask同步员工信息，变更{}条", ldapNonExistList.size());
        List<LdapEhrEmp> allList = ldapNonExistList;
        allList.addAll(ldapList);
        return allList;
    }

    @Transactional(rollbackFor = Exception.class)
    public List<LdapEhrDept> syncDept() {
        List<LdapEhrDept> deptInfoList = Collections.EMPTY_LIST;
        //B1.采集EHR原表数据
        List<TAmEhrDeptinfoEntity> ehrList = ehrDeptRepo.getDeptInfoList();
        List<Hrmdepartment> oaList = oaDeptRepo.findAllByOutkeyNotNull();
        Map<Integer, Hrmsubcompany> compMap = oaCompRepo.findAll().stream().collect(Collectors.toMap(Hrmsubcompany::getId, o -> o));
        logger.info("部门信息采集-ehr:{}条", CollectionUtils.isEmpty(ehrList) ? 0 : ehrList.size());
        logger.info("部门信息采集-oa:{}条", CollectionUtils.isEmpty(oaList) ? 0 : oaList.size());
        Map<String, TAmEhrDeptinfoEntity> ehrMap = CollectionUtils.isEmpty(ehrList) ? Collections.EMPTY_MAP :
                ehrList.stream().collect(Collectors.toMap(o -> String.valueOf(o.getDepid()), o -> o));
        Map<Integer, Hrmdepartment> oaMap = CollectionUtils.isEmpty(oaList) ? Collections.EMPTY_MAP :
                oaList.stream().collect(Collectors.toMap(Hrmdepartment::isId, o -> o));

        if (!CollectionUtils.isEmpty(oaList)) {
//            Map<String, List<TAmEhrDeptinfoEntity>> ehrMap = ehrList.stream().collect(Collectors.groupingBy(TAmEhrDeptinfoEntity::getDtitle));
            deptInfoList = oaList.stream()
                    .filter(o -> Strings.isNotBlank(o.getOutkey()))
                    .map(oaDept -> {
                        LdapEhrDept ldapDept = new LdapEhrDept();
                        //ehr的depId和oa的outkey关联
                        if (ehrMap.containsKey(String.valueOf(oaDept.getOutkey()))) {
                            TAmEhrDeptinfoEntity ehrDept = ehrMap.get(String.valueOf(oaDept.getOutkey()));
                            org.springframework.beans.BeanUtils.copyProperties(ehrDept, ldapDept);
                        }
                        //同名部门，通过公司区别
                        ldapDept.setDepid(Integer.valueOf(oaDept.getOutkey()));
                        ldapDept.setComptitle(compMap.containsKey(oaDept.getSubcompanyid1()) ? compMap.get(oaDept.getSubcompanyid1()).getSubcompanyname() : null);
                        ldapDept.setDtitle(oaDept.getDepartmentname());
                        ldapDept.setDepgrade(oaDept.getTlevel() == 2 ? "一级部门" : oaDept.getTlevel() == 3 ? "二级部门" :
                                oaDept.getTlevel() == 4 ? "三级部门" : "四级部门");
                        ldapDept.setOaDeptId(oaDept.isId());
                        ldapDept.setSuperOaDeptId(oaDept.getSupdepid());
                        ldapDept.setCanceled(oaDept.getCanceled());
                        //设置上级部门id
                        if (Objects.nonNull(oaDept.getSupdepid()) && oaMap.containsKey(oaDept.getSupdepid())) {
                            Hrmdepartment supDept = oaMap.get(oaDept.getSupdepid());
                            Integer supId = Strings.isNotBlank(supDept.getOutkey()) ? Integer.valueOf(supDept.getOutkey()) : null;
                            ldapDept.setAdminid(supId);
                            ldapDept.setAtitle(supDept.getDepartmentname());
                            ldapDept.setSuperDeptId(supId);
                        }
                        return ldapDept;
                    })
                    .collect(Collectors.toList());
            //B2：清空部门信息表
            ldapEhrDeptRepo.truncateTableEhrDept();
            //B3.保存
            ldapEhrDeptRepo.saveAll(deptInfoList);
            ldapEhrDeptRepo.flush();
        }
        logger.info("syncEhrDataTask同步部门信息完成{}条", deptInfoList.size());
        return deptInfoList;
    }

    @Transactional(rollbackFor = Exception.class)
    public List<LdapEhrComp> syncComp() {
        //B1.采集EHR原表数据
        List<Hrmsubcompany> oaList = oaCompRepo.findAllByCanceledIsNull();
        logger.info("公司信息采集-oa:{}条", CollectionUtils.isEmpty(oaList) ? 0 : oaList.size());
        List<LdapEhrComp> collect = oaList.stream()
                .map(oaDept -> {
                    LdapEhrComp newDept = new LdapEhrComp();
                    org.springframework.beans.BeanUtils.copyProperties(oaDept, newDept);
                    newDept.setId(null);
                    newDept.setOaCompId(oaDept.getId());
                    return newDept;
                })
                .collect(Collectors.toList());
        //B2：清空部门信息表
        ldapEhrCompRepo.truncateTableEhrCompy();
        //B3.保存
        ldapEhrCompRepo.saveAll(collect);
        ldapEhrDeptRepo.flush();
        logger.info("syncEhrDataTask同步公司信息完成{}条", collect.size());
        return collect;
    }
}